import random
import re

from flask import request, abort, current_app, make_response, Response, jsonify

from info import sr, db
from info.lib.yuntongxun.sms import CCP
from info.models import User
from info.modules.passport import passport_blue

from info.utils.captcha.pic_captcha import captcha
from info.utils.response_code import RET, error_map


# 获取图片验证码
@passport_blue.route('/get_img_code')
def get_img_code():
    # 1.获取参数（获取图片的key）
    img_code_id = request.args.get('img_code_id')

    # 2.验证参数 是否有key的值
    if not img_code_id:
        return abort(403)

    # 3.生成图片验证码(三个参数)
    name, img_code_text, img_code_bytes = captcha.generate_captcha()

    # 4.将图片的key和文字验证码(key是键 验证码是值)存到数据库中下次请求时使用
    try:
        sr.set('img_code_id'+img_code_id, img_code_text, ex=300)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(500)

    # 5.定义返回图片的格式content-type类型为img
    response = make_response(img_code_bytes)  # type:Response
    response.content_type = 'image/jpeg'
    # response.headers['Content-type'] = 'image/jpeg'

    return response


# 获取短信验证码
@passport_blue.route('/get_sms_code', methods=['POST'])
def get_sms_code():
    # 1.获取前段请求的数据 mobile,img_code_id(图片的key), img_code(图片中的text文字)
    img_code_id = request.json.get('img_code_id')
    mobile = request.json.get('mobile')
    img_code = request.json.get('img_code')

    # 2.验证参数(完整性,参数是否正确)
    if not all([img_code_id, img_code, mobile]):    # 参数不完整
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 2.1验证手机号是否正确
    if not re.match(r'1[35678]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmasg=error_map[RET.PARAMERR])

    # 3.从数据库中获取key对应的值(验证码文字)判断是否与客户发一致
    try:
        real_img_text = sr.get('img_code_id' + img_code_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmasg=error_map[RET.DBERR])

    # 验证图片验证码手机是否过期
    if not real_img_text:
        return jsonify(errno=RET.PARAMERR, errmasg='验证码过期')

    # 验证验证码正确性
    if real_img_text != img_code.upper():
        return jsonify(errno=RET.PARAMERR, errmasg='验证码错误')

    # 4.验证正确之后给手机发送短信
    # 生成验证码
    rand_num = '%04d' % random.randint(0, 9999)
    current_app.logger.info(rand_num)
    result = CCP().send_template_sms(mobile, [rand_num, 2], 1)
    if result == -1:
        return jsonify(errno=RET.THIRDERR, errmasg=error_map[RET.THIRDERR])

    # 5.然后再把手机和短信验证码存储到数据库中(mobile为键短信验证码为值)
    try:
        sr.set('sms_code'+mobile, rand_num, ex=60)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmasg=error_map[RET.DBERR])
    return jsonify(errno=RET.OK, errmasg=error_map[RET.OK])

    # return jsonify(errno=RET.OK, errmasg=error_map[RET.OK])


# 注册用户
@passport_blue.route('/register', methods=['POST'])
def register():
    # 1.获取参数(手机号,短信验证码,密码)
    mobile = request.json.get('mobile')
    password = request.json.get('password')
    sms_code = request.json.get('sms_code')

    # 2.校验数据(参数完整性, 手机号)
    if not all([mobile, password, sms_code]):
        return jsonify(errno=RET.PARAMERR, errmasg=error_map[RET.PARAMERR])
    if not re.match(r'1[35678]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmasg=error_map[RET.PARAMERR])

    # 3.根据手机号从数据库中获取短信验证码
    real_sms_code = sr.get('sms_code' + mobile)

    # 4.校验短信验证码
    # 判断验证码是否过期
    if not real_sms_code:
        return jsonify(errno=RET.PARAMERR, errmasg='短信验证码过期')

    # 判断验证码错误
    if real_sms_code != sms_code:
        return jsonify(errno=RET.PARAMERR, errmasg='短信验证码错误')

    # 5.成功,保存数据到mysql数据库
    user = User()
    user.mobile = mobile
    user.password_hash = password
    user.nick_name = mobile
    try:
        db.session.add(user)
        db.session.commit()
    except BaseException as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmasg=error_map[RET.DBERR])

    # 6.返回响应
    return jsonify(errno=RET.OK, errmasg=error_map[RET.OK])
